home *** CD-ROM | disk | FTP | other *** search
- /*
- ** $RCSfile: UnMount.c,v $
- ** $Filename: UnMount.c $
- ** $Revision: 0.1 $
- ** $Date: 1995/04/29 17:33:51 $
- **
- ** Try to Shutdown or at least Inhibit DOS-Handlers (version 0.5)
- **
- ** (C) Copyright 1995 by Etienne Vogt
- */
-
- #include <exec/alerts.h>
- #include <exec/memory.h>
- #include <dos/dosextens.h>
- #include <dos/dostags.h>
- #include <workbench/startup.h>
- #define __USE_SYSBASE
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <clib/alib_protos.h>
- #include <string.h>
-
- struct ExecBase *SysBase;
- struct DosLibrary *DOSBase;
- static struct WBStartup *wbmsg;
- static struct RDArgs *myrda;
-
- static UBYTE version[] = "$VER: UnMount 0.5 (4.11.95)";
- static UBYTE template[] = "DEVICE,INHIBIT/S,RETRY/K/N,ALL/S,FREENODE/S";
-
- #define DBUFSIZE 16
- #define DNAMSIZE 14
-
- struct devBuffer
- { struct devBuffer *dbf_Link;
- UBYTE dbf_Name[DBUFSIZE][DNAMSIZE];
- };
-
- #define OPT_DEVICE 0
- #define OPT_INHIBIT 1
- #define OPT_RETRY 2
- #define OPT_ALL 3
- #define OPT_FREENODE 4
- #define OPTMAX 5
-
- ULONG __saveds main(void);
- static void cleanexit(ULONG rc);
- static int unmount(STRPTR device, int inhibit, int retry, BOOL verbose);
- static struct devBuffer *getdevices(int *nodes);
- static void freedbufs(struct devBuffer *dbufs);
- static void killdevices(struct devBuffer *dbuf, int numdevs, int inhibit, int retry, int freenode);
- static void freeNode(STRPTR device);
-
- ULONG __saveds main(void) /* No startup code */
- {
- struct Process *myproc;
- LONG opts[OPTMAX];
- ULONG rc = 0;
-
- SysBase = *(struct ExecBase **)4;
- DOSBase = NULL;
- wbmsg = NULL;
- myrda = NULL;
-
- myproc = (struct Process *)FindTask(NULL);
- if ((DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",36)) == NULL)
- { Alert(AT_Recovery|AG_OpenLib|AO_DOSLib);
- return 100;
- }
-
- if (!(myproc->pr_CLI)) /* If started from WB, exit cleanly */
- { WaitPort(&(myproc->pr_MsgPort));
- wbmsg = (struct WBStartup *)GetMsg(&(myproc->pr_MsgPort));
- cleanexit(20);
- }
- else
- { APTR oldwinptr;
- int retrycount = 10, error;
-
- memset((char *)opts, 0, sizeof(opts));
- if ((myrda = ReadArgs(template, opts, NULL)) == NULL)
- { PrintFault(IoErr(),"UnMount");
- cleanexit(20);
- }
-
- if (opts[OPT_RETRY]) retrycount = *((LONG *)opts[OPT_RETRY]);
-
- oldwinptr = myproc->pr_WindowPtr; /* Disable DOS Requesters */
- myproc->pr_WindowPtr = (APTR)(-1L);
-
- if (opts[OPT_DEVICE])
- { struct DosList *dol;
- char buffer[DNAMSIZE];
- STRPTR colon;
-
- dol = LockDosList(LDF_DEVICES | LDF_READ);
- strncpy(buffer, (STRPTR)opts[OPT_DEVICE], sizeof(buffer));
- if (colon = (UBYTE *)strchr(buffer,':')) *colon = (UBYTE)0;
- else buffer[DNAMSIZE-1] = (UBYTE)0;
- if (dol = FindDosEntry(dol, buffer, LDF_DEVICES))
- { UnLockDosList(LDF_DEVICES | LDF_READ);
- if (error = unmount((STRPTR)opts[OPT_DEVICE], opts[OPT_INHIBIT], retrycount, TRUE))
- { PrintFault(error, "UnMount");
- rc = 10;
- }
- else if (opts[OPT_FREENODE]) freeNode((STRPTR)opts[OPT_DEVICE]);
- }
- else
- { UnLockDosList(LDF_DEVICES | LDF_READ);
- PrintFault(ERROR_DEVICE_NOT_MOUNTED, "UnMount");
- rc = 20;
- }
-
- }
- else if (opts[OPT_ALL])
- { struct devBuffer *dbuf;
- int numdevs;
-
- if (dbuf = getdevices(&numdevs)) killdevices(dbuf, numdevs, opts[OPT_INHIBIT], retrycount, opts[OPT_FREENODE]);
- else
- { PrintFault(ERROR_NO_FREE_STORE, "UnMount");
- rc = 20;
- }
- }
- else
- { PrintFault(ERROR_REQUIRED_ARG_MISSING, "UnMount");
- rc = 20;
- }
-
- myproc->pr_WindowPtr = oldwinptr;
- }
- cleanexit(rc);
- }
-
- static void cleanexit(ULONG rc)
- {
- if (myrda) FreeArgs(myrda);
- if (DOSBase) CloseLibrary((struct Library *)DOSBase);
- if (wbmsg)
- { Forbid();
- ReplyMsg((struct Message *)wbmsg);
- }
- Exit(rc);
- }
-
- static int unmount(STRPTR device, int inhibit, int retry, BOOL verbose)
- { struct DevProc *dvp;
- int count = 0, rc = 0;
-
- if (!strchr(device,':')) return ERROR_INVALID_COMPONENT_NAME;
- if (dvp = GetDeviceProc(device, NULL))
- { if (DoPkt0(dvp->dvp_Port, ACTION_DIE) == DOSFALSE)
- { rc = IoErr();
- if (IsFileSystem(device) && inhibit)
- { if (verbose) Printf("UnMount : Couldn't kill device %s, Trying to inhibit...\n", device);
- do
- { if (Inhibit(device, DOSTRUE)) break;
- else if ((rc = IoErr()) == ERROR_ACTION_NOT_KNOWN) count = retry;
- else Delay(TICKS_PER_SECOND);
- } while (++count < retry);
- if (count < retry) rc = 0;
- }
- }
- FreeDeviceProc(dvp);
- }
- else rc = IoErr();
- return rc;
- }
-
- static struct devBuffer *getdevices(int *nodes)
- { struct devBuffer *dbuf;
-
- if (dbuf = AllocVec(sizeof(struct devBuffer), MEMF_PUBLIC | MEMF_CLEAR))
- { struct DosList *dol;
- struct devBuffer *db = dbuf;
- int i = 0;
-
- dol = LockDosList(LDF_DEVICES | LDF_READ);
- *nodes = 0;
- while (dol = NextDosEntry(dol, LDF_DEVICES))
- { UBYTE namlen;
- UBYTE *namptr;
-
- if (dol->dol_Task == NULL) continue;
- namptr = BADDR(dol->dol_Name);
- namlen = (namptr[0] < DNAMSIZE - 1 ? namptr[0] : DNAMSIZE - 2);
- strncpy(db->dbf_Name[i], namptr + 1, namlen);
- db->dbf_Name[i][namlen] = ':';
- db->dbf_Name[i][namlen+1] = '\0';
- if (strcmp(db->dbf_Name[i], "RAM:") == 0) continue;
- (*nodes)++;
-
- if (++i == DBUFSIZE)
- { struct devBuffer *db1;
-
- if (db1 = AllocVec(sizeof(struct devBuffer), MEMF_PUBLIC | MEMF_CLEAR))
- { db->dbf_Link = db1;
- db = db1;
- i = 0;
- }
- else
- { UnLockDosList(LDF_DEVICES | LDF_READ);
- freedbufs(dbuf);
- return NULL;
- }
- }
- }
- UnLockDosList(LDF_DEVICES | LDF_READ);
- }
- return dbuf;
- }
-
- static void freedbufs(struct devBuffer *dbufs)
- { struct devBuffer *nextdb;
-
- do
- { nextdb = dbufs->dbf_Link;
- FreeVec(dbufs);
- } while (dbufs = nextdb);
- }
-
- static void killdevices(struct devBuffer *dbuf, int numdevs, int inhibit, int retry, int freenode)
- { struct devBuffer *db = dbuf;
- STRPTR devname;
- int j, i, error;
-
- for (j = 0, i = 0 ; j < numdevs ; j++)
- { devname = db->dbf_Name[i];
- if (IsFileSystem(devname))
- { Printf("Unmounting device %s\n", db->dbf_Name[i]);
- if (error = unmount(devname, inhibit, retry, FALSE)) PrintFault(error, "UnMount");
- else if (freenode) freeNode(devname);
- }
-
- if (++i == DBUFSIZE)
- { db = db->dbf_Link;
- i = 0;
- }
- }
- freedbufs(dbuf);
- }
-
- static void freeNode(STRPTR device)
- { struct DosList *dol;
- char buffer[DNAMSIZE];
- STRPTR colon;
-
- dol = LockDosList(LDF_DEVICES | LDF_WRITE);
- strncpy(buffer, device, sizeof(buffer));
- if (colon = (UBYTE *)strchr(buffer,':')) *colon = (UBYTE)0;
- else buffer[DNAMSIZE-1] = (UBYTE)0;
- if (dol = FindDosEntry(dol, buffer, LDF_DEVICES))
- { RemDosEntry(dol);
- FreeDosEntry(dol);
- }
- UnLockDosList(LDF_DEVICES | LDF_WRITE);
- }
-